/*********************************************************************************
 *FileName:  lin21.c
 *Author:    ChenJiehong
 *Version:   V1.0
 *Date:      2024-03-13
 ****************************************Includes***********************************/
#include "lin21.h"
#include "swtimer.h"
#include "lin_api.h"

#include "bdc.h"
#include "sensor.h"
#include "eeprom.h"

/***************************************Variables***********************************/

/* LIN回调函数声明 */
void UnconditionalSubscribedCmdsHandle(LIN_Device_Frame_t const *frame);
void UnconditionalPublishedCmdsISR(LIN_Device_Frame_t *const frame);
void DiagnosticSubscribedCmdsHandle(const DiagReqInfo_t *const diagReq, DiagRspInfo_t *const diagRsp);
void l_ifc_sleep_entered_callout(l_SleepReason Reason);


LIN_Device_Frame_t UnconditionalCmdsTable[DEFAULT_LINS_FID_SIZE] = {
    [0] =
        {
            .frame_id = 0x13,
            .msg_type = LIN_MSG_TYPE_RX,
            .checksum_type = LIN_CHECKSUM_ENHANCED,
            .length = 8,
            .frameIsValid = true,
        },
    [1] =
        {
            .frame_id = 0x23,
            .msg_type = LIN_MSG_TYPE_TX,
            .checksum_type = LIN_CHECKSUM_ENHANCED,
            .length = 8,
            .frameIsValid = true,
        },
};


/* 初始化LIN信号 */
l_sl1_EWV_Res_data_t *EWV_Res_data = (l_sl1_EWV_Res_data_t *)UnconditionalCmdsTable[1].data;
l_sl1_EWV_Set_data_t *EWV_Set_data = (l_sl1_EWV_Set_data_t *)UnconditionalCmdsTable[0].data;
/* 初始化LIN信号标准位 */
l_sl1_flags_t	l_sl1_flags;
/* 初始化NAD */
l_u8 l_ConfiguredNAD = INIT_LINS_NAD_ADDR;



/*  LIN command handle callbacks declarations  */
static ls_LinsFramesCallback_t linsFramesCallback = {
    UnconditionalSubscribedCmdsHandle,	/* received data from master */
    UnconditionalPublishedCmdsISR,		/* send data to master */
    DiagnosticSubscribedCmdsHandle,		/* Diagnostic and MultiPDU received data from master */
    NULL,                           	/* special functional NAD (0x7E) handler*/
    l_ifc_sleep_entered_callout,        /* Diagnostic sleep request from master   */
};

uint8_t g_SlaveSlientSleep = 0;
uint8_t g_SlaveCommandSleep = 0;
extern EEPROM_ActuatorParams_t EEPROM_ActuatorParams;
/***************************************Functions***********************************/


void lins_init(void)
{
	SYSCTRL_Unlock();
    RCC_APBPeriphClockCmd(RCC_APBPeriph_LINUART, ENABLE);
    RCC_APBPeriphClockCmd(RCC_APBPeriph_LINPORT, ENABLE);
	
    /* UART Rx Pin routed to LIN */
    LINPORT->CR_b.LAIS = 0;
    LINPORT->CR_b.TXOS = 0;
    LINPORT->CR_b.RXEN = 1;
    /* Linport still work at uv mode */
    LINPORT->CR_b.LOM = 1;
    /* Enable Linport */
    LINPORT->CR_b.LINPORTEN = 1;

    /* Disable UART when changing configuration */
    LINUART->CR = 0x00;

    LINUART->CR_b.TXFE = 1;
    LINUART->CR_b.RXFE = 1;

	LINPORT->CR_b.RXFT = 11;
    LINUART->CR_b.TXLOOPE = 0;
    LINUART->CR_b.BRRWINE = 1;
    LINUART->CR_b.LINMODE = 1;

    LINUART->IEN_b.RXFLCIE = 1;
    LINUART->IEN_b.BRROK = 1;

    NVIC_EnableIRQ(LINUART_IRQn);
    NVIC_SetPriority(LINUART_IRQn, 0);

    /* reset all UART IRQ pending flags */
    LINUART->ISR = 0xFFFF;
    /* When detec LIN Frame break + sync, Disable TX RX function,
       TXRXEN will be enabled if the break + sync frame be deteced. */
    LINUART->CR_b.TXRXE = 0;
    /* set auto baudrate */
    LINUART->CR_b.AUTOBRR = 1;

    LINUART->CR_b.UE = 1;
	
	/* 注册软件定时器，用于诊断帧响应超时，和LIN总线静默*/
    swtimer_register(SWTIMER_LIN_N_AS_DELAY, C_PI_TICKS_1S, TIMER_ONE_SHOT_MODE);
    swtimer_register(SWTIMER_LIN_TIMEOUT, C_PI_TICKS_100MS, TIMER_PERIODIC_MODE);	
    swtimer_start(SWTIMER_LIN_TIMEOUT);

}


void l_N_AS_TimeoutStart(void)
{
    swtimer_start(SWTIMER_LIN_N_AS_DELAY);
}

void lin21_Init(void)
{
    (void)l_sys_init();
    (void)l_ifc_init_sl1();

    ls_register_services(UnconditionalCmdsTable, (l_u8)(sizeof(UnconditionalCmdsTable) / sizeof(LIN_Device_Frame_t)), &linsFramesCallback);
	
#if (SL_HAS_SAVE_CONFIGURATION_SERVICE == 1)	
	uint8_t lin_config[DEFAULT_LINS_FID_SIZE+1];
	uint8_t lin_cfg_len = DEFAULT_LINS_FID_SIZE+1;
	if(EEPROM_ReadLINconfig(lin_config, lin_cfg_len))
	{
		ld_set_configuration(lin_config, lin_cfg_len);
	}
	else
	{
        /* 如果没有保存过NAD PID 对ID进行存储 方便用于Bootloader区分NAD */
		ld_load_configuration(lin_config, DEFAULT_LINS_FID_SIZE+1);	
		EEPROM_StoreLINconfig(lin_config, DEFAULT_LINS_FID_SIZE+1);
	}
#endif /* (SL_HAS_SAVE_CONFIGURATION_SERVICE == 1) */
		
}



void ld_set_configuration(const l_u8* const data, uint8_t length)
{
	l_ConfiguredNAD = data[0];
	
	for(uint8_t i=0;i<length-1;i++)
	{
		UnconditionalCmdsTable[i].frame_id = data[i+1];
	}
}

void ld_load_configuration(l_u8* data, uint8_t length)
{
	data[0] = l_ConfiguredNAD;
	
	for(uint8_t i=0;i<length-1;i++)
	{
		data[i+1] = UnconditionalCmdsTable[i].frame_id;
	}
}

void lin21_GotoSleep(void)
{
    /* Unlock system control register */
    SYSCTRL->LKKEYR = SYSCTRL_UNLOCK_KEY;
    /* Enter Sleep Mode */
    SYSCTRL->LPCR_b.SLEEP = 1;
}

void ls_ErrorDetected(l_LinError Error)
{
	
    switch (Error)
    {
    case l_erIdParity:
    case l_erCheckSum:
    case l_erBit:
    case l_erDataFraming:
    case l_erBreakDetected:

        l_bool_wr_response_error(true);
        break;
    default:
        break;
    }
}

void l_ifc_sleep_entered_callout(l_SleepReason Reason)
{
	if(Reason == l_reasonMaster)
	{
		/* LIN诊断帧休眠 */
		//lin21_GotoSleep();
		g_SlaveCommandSleep = 1;
		u16GotoSleepDelay = 40;

	}
	else
	{
		/* LIN静默(4s) */
		//lin21_GotoSleep();
		g_SlaveSlientSleep = 1;           //使能LIN异常保护位置
	}
    
}

void UnconditionalSubscribedCmdsHandle(LIN_Device_Frame_t const *frame)
{
    if (frame->frame_id == UnconditionalCmdsTable[0].frame_id)
    {
        l_sl1_flags.f_EWV_Set = 1;
		g_SlaveSlientSleep = 0;
    }
}

void UnconditionalPublishedCmdsISR(LIN_Device_Frame_t *const frame)
{
    if (frame->frame_id == UnconditionalCmdsTable[1].frame_id)
    {
        l_sl1_flags.f_EWV_Res = 1;
		g_SlaveSlientSleep = 0;
    }
}


uint8_t LNCI_HandleDiagCustomRequest(const DiagReqInfo_t *const diagReq, DiagRspInfo_t *const diagRsp)
{
    uint8_t response = false;
	diagRsp->type = PDU_TYPE_SINGLE_PDU;
	if ((diagReq->nad == l_ConfiguredNAD) || (diagReq->nad == 0x7FU))
	{
		UserCustomFrame_t *CustomDiag = (UserCustomFrame_t *)((void *)diagReq->payload);
		
		if(CustomDiag->head == 0x3598)
		{
			if(CustomDiag->cmd[0] == 0x37 && CustomDiag->cmd[1] == 0x05 && CustomDiag->cmd[2] == 0xDD)
			{
				extern void Enter_Calibration(void);
				Enter_Calibration();

			}
			
			if(CustomDiag->cmd[0] == 0x37 && CustomDiag->cmd[1] == 0x05 && CustomDiag->cmd[2] == 0xEE)
			{
				extern void Enter_TEMBTestmode(void);
				//Enter_TEMBTestmode();

			}
			

	
			
			if(CustomDiag->cmd[2] == 0x60)
			{
				//--------------------------------自定义版本说明-----------------------------
				// 1：20240329母版
				// 2：20240423母版：底层V4.0
				// 3：20240729母版：底层V6.0
				// 4：
				//---------------------------------------------------------------------------
				
                diagRsp->nad = l_ConfiguredNAD;
                diagRsp->packLength = 5; /* 不包括RSID */
                diagRsp->rsid = 0xDB;
				diagRsp->payload[0] = 0;  //  客户代码1：开沃六通阀13-23，0-43
				diagRsp->payload[1] = 24;   //  年
				diagRsp->payload[2] = 7;    //  月
				diagRsp->payload[3] = 29;   //  日
				diagRsp->payload[4] = 3;    //  自定义版本
                response = true;
			}
			
			if(CustomDiag->cmd[2] == 0xCE)
			{
				/* prepare slave response */
				uint16_t u16_Temp_adc = Actuator.i16Temperature +60;
				
                diagRsp->nad = l_ConfiguredNAD;
                diagRsp->packLength = 5; /* 不包括RSID */
                diagRsp->rsid = 0xDB;
				diagRsp->payload[0] = (uint8_t)(u16_Temp_adc& 0xFFU);        //芯片温度
				diagRsp->payload[1] = (uint8_t)(Actuator.Motor.u16Current & 0xFFU);     //电流低八位
				diagRsp->payload[2] = (uint8_t)(Actuator.Motor.u16Current >> 8);        //电流高八位
				diagRsp->payload[3] = (uint8_t)(Actuator.u16SupplyVoltage & 0xFFU);     //输入电压低八位
				diagRsp->payload[4] = (uint8_t)(Actuator.u16SupplyVoltage >> 8);       	//输入电压高八位
                response = true;
			}
			
			if(CustomDiag->cmd[2] == 0x5F)
			{
                diagRsp->nad = l_ConfiguredNAD;
                diagRsp->packLength = 5; /* 不包括RSID */
                diagRsp->rsid = 0xDB;
				diagRsp->payload[0] = (uint8_t)RESISTANCE_MAX_OFFSET;    // 备用
				diagRsp->payload[1] = 0;    // 备用
				diagRsp->payload[2] = (uint8_t)POSITION_DEAD;    // 备用
				diagRsp->payload[3] = (uint8_t)POSITION_PID_DEAD;    // 电机运动停止判定死区
				diagRsp->payload[4] = (uint8_t)POSITION_DEAD_STALL;    // 备用
                response = true;
			}
			
			if(CustomDiag->cmd[2] == 0x63)
			{
                diagRsp->nad = l_ConfiguredNAD;
                diagRsp->packLength = 5; /* 不包括RSID */
                diagRsp->rsid = 0xDB;
				diagRsp->payload[0] = 0;    // 备用
				diagRsp->payload[1] = (uint8_t)(Position_Para.u16Sensor_Min & 0xFFU);     //工作范围1低八位
				diagRsp->payload[2] = (uint8_t)(Position_Para.u16Sensor_Min >> 8);        //工作范围1高八位
				diagRsp->payload[3] = (uint8_t)(Position_Para.u16Sensor_Max & 0xFFU);     //工作范围2低八位
				diagRsp->payload[4] = (uint8_t)(Position_Para.u16Sensor_Max >> 8);        //工作范围2高八位
                response = true;
			}
			
			if(CustomDiag->cmd[2] == 0x64)
			{
                diagRsp->nad = l_ConfiguredNAD;
                diagRsp->packLength = 5; /* 不包括RSID */
                diagRsp->rsid = 0xDB;
				diagRsp->payload[0] = 1;       //小版本计数/////////////////////////////////
				diagRsp->payload[1] = (uint8_t)(Actuator.u16TargetPosition & 0xFFU);     //
				diagRsp->payload[2] = (uint8_t)(Actuator.u16TargetPosition >> 8);        //
				diagRsp->payload[3] = (uint8_t)(Actuator.u16ActualPosition & 0xFFU); 
				diagRsp->payload[4] = (uint8_t)(Actuator.u16ActualPosition >> 8);  
                response = true;
			}

			if(CustomDiag->cmd[2] == 0x65)
			{
                diagRsp->nad = l_ConfiguredNAD;
                diagRsp->packLength = 5; /* 不包括RSID */
                diagRsp->rsid = 0xDB;
				diagRsp->payload[0] = 0;       //备用 
				diagRsp->payload[1] = (uint8_t)(g_u16EndSTopMin & 0xFFU);     //堵转值1低八位
				diagRsp->payload[2] = (uint8_t)(g_u16EndSTopMin >> 8);        //堵转值1高八位
				diagRsp->payload[3] = (uint8_t)(g_u16EndSTopMax & 0xFFU);     //堵转值2低八位
				diagRsp->payload[4] = (uint8_t)(g_u16EndSTopMax >> 8);        //堵转值2高八位
                response = true;
			}

			if(CustomDiag->cmd[2] == 0x66)
			{
				//---------------------------------------------------------------------------
				// 0：未定义
				// 1：MLX81315
				// 2：MLX81325
				// 3：MLX81332
				// 4：英迪芯Ind83219 + ELMOS
				// 5：英迪芯Ind83219 + 纳芯微7312A
				// 6：纳芯微NSUC1610（三代小扭矩，电位器）
				// 7：纳芯微NSUC1610（二代无刷）
				// 8：纳芯微NSUC1610（双驱，电位器）
				// 9：纳芯微NSUC1610（2D霍尔）
				//---------------------------------------------------------------------------
				
                diagRsp->nad = l_ConfiguredNAD;
                diagRsp->packLength = 5; /* 不包括RSID */
                diagRsp->rsid = 0xDB;
				diagRsp->payload[0] = (uint8_t)9;        //芯片型号：纳芯微NSUC1610（2D霍尔）
				diagRsp->payload[1] = (uint8_t)(RESISTANCE_MIN_NORMAL & 0xFFU);     //
				diagRsp->payload[2] = (uint8_t)(RESISTANCE_MIN_NORMAL >> 8);        //
				diagRsp->payload[3] = (uint8_t)(RESISTANCE_MAX_NORMAL & 0xFFU); 
				diagRsp->payload[4] = (uint8_t)(RESISTANCE_MAX_NORMAL >> 8); 
                response = true;
			}
			
			if(CustomDiag->cmd[2] == 0x67)
			{
                diagRsp->nad = l_ConfiguredNAD;
                diagRsp->packLength = 5; /* 不包括RSID */
                diagRsp->rsid = 0xDB;
				diagRsp->payload[0] = (uint8_t)43;  //  客户代码1：开沃六通阀13-23，0-43
				diagRsp->payload[1] = (uint8_t)(EEPROM_ActuatorParams.Actuator_Sensor_Cnt & 0xFFU);    //标定次数
				diagRsp->payload[2] = (uint8_t)(EEPROM_ActuatorParams.Actuator_Sensor_Cnt >> 8);       //标定次数
				diagRsp->payload[3] = (uint8_t)(Actuator.Motor.u16Duty & 0xFFU); 
				diagRsp->payload[4] = (uint8_t)(Actuator.Motor.u16Duty >> 8); 
                response = true;
			}
		}
	}
	
	return response; 
}

void DiagnosticSubscribedCmdsHandle(const DiagReqInfo_t *const diagReq, DiagRspInfo_t *const diagRsp)
{
    if (diagReq->type == PDU_TYPE_SINGLE_PDU)
    {
        if (diagReq->sid >= LIN_SID_ASSIGN_NAD && diagReq->sid <= LIN_SID_ASSIGN_FRAME_ID_RANGE)
        {
            /* handle Node configuration and Identification commands*/
            if (LNCI_HandleNodeCfgIdentifyRequest(diagReq, diagRsp))
            {
                l_handle_diagnostic_response(diagRsp);
            }
        }
#if (SL_HAS_BOOTLOADER_SERVICE == 1)
        else if (diagReq->sid == LIN_SID_APP_DIAG_BOOT_MODE && diagReq->packLength == sizeof(EnterBootloaderFrame_t))
        {
			
            EnterBootloaderFrame_t *boot = (EnterBootloaderFrame_t *)((void *)diagReq->payload);
            if (boot->command == BOOT_MODE_HANDSHAKE && boot->magicKey == BOOT_MODE_MAGIC_KEY_HANDSHAKE)
            {
                NVIC_SystemReset();
            }
        }
#endif /* (SL_HAS_BOOTLOADER_SERVICE == 1) */	
		else if(diagReq->sid == LIN_SID_USER_CUSTOM && diagReq->packLength == sizeof(UserCustomFrame_t))
		{
			/* 天博诊断帧 */
            if (LNCI_HandleDiagCustomRequest(diagReq, diagRsp))
            {
                l_handle_diagnostic_response(diagRsp);
            }
		}
		else 
		{
			
		}
    }
    else
    {
    }
}



void lin_hander(void)
{
    if (swtimer_isTriggered(SWTIMER_LIN_N_AS_DELAY))
    {
        l_DiagClearPendingResponse();
    }

	
    if (swtimer_isTriggered(SWTIMER_LIN_TIMEOUT))
    {
        l_BusSilentCheck();		/* 该函数需要100ms调用1次 */
    }
	
#if (SL_HAS_SAVE_CONFIGURATION_SERVICE == 1)	
    l_s_IfcStatus_t status;
    status.word = l_ifc_read_status_sl1();
    if (status.mapped.SaveConfig != 0)
    {
		uint8_t cofig[DEFAULT_LINS_FID_SIZE+1];
		ld_load_configuration(cofig, DEFAULT_LINS_FID_SIZE+1);	
		EEPROM_StoreLINconfig(cofig, DEFAULT_LINS_FID_SIZE+1);
    }
    else
    {
        /* nothing to be done */
    }
#endif /* (SL_HAS_SAVE_CONFIGURATION_SERVICE == 1) */

}


/***************************************END OF FILE*********************************/
